package servidor;

import comunicacion.Cliente;
import estado.EstadoPartida;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import mensaje.*;

/**
 * Responsabilidad: gestionar la partida, crea la partida, registra y elimina jugadores,
 * da la orden de inicio de la partida cuando se registran todos los jugadores.
 */

public class GestorPartida {

    private EstadoPartida estadoPartida;
    private int tipoEscenario, numJugadores, id;
    private HashMap jugadores;
    private GestorSalida gestorSalida;
    private GestorJuego gestorJuego;

    public GestorPartida(Mensaje mensaje, EstadoPartida estadoPartida) {
        this.estadoPartida = estadoPartida;
        id = 0;
        crearPartida((MsjCrearPartida) mensaje);
    }

    public void crearPartida(MsjCrearPartida mensajeCrearPartida){
        this.tipoEscenario = mensajeCrearPartida.getTipoEscenario();
        this.numJugadores = mensajeCrearPartida.getNumJugadores();
        jugadores = new HashMap(numJugadores);
        estadoPartida.setEsperandoJugadores();
        System.out.println("...Partida Creada!!...");
        gestorSalida = new GestorSalida(jugadores);
        gestorSalida.enviar(true, mensajeCrearPartida.cliente);
    }

    public void agregarJugador(Mensaje mensaje){
        MsjUnionJugador mensajeUnionJugador = (MsjUnionJugador) mensaje;
        //Cliente cliente = mensajeUnionJugador.cliente;
        mensajeUnionJugador.cliente.setId(id++);
        mensajeUnionJugador.cliente.setNombre(mensajeUnionJugador.getNombre());
        mensajeUnionJugador.cliente.setTipoPersonaje(mensajeUnionJugador.getTipoPersonaje());
        jugadores.put(mensajeUnionJugador.cliente.getId(), mensajeUnionJugador.cliente);
        System.out.println("...Jugador agregado: Jugador " + ((Cliente)jugadores.get(mensajeUnionJugador.cliente.getId())).getId());
        gestorSalida.enviar(true, mensajeUnionJugador.cliente.getId());
        
        //if(mensajeUnionJugador.cliente.getId() == (numJugadores-1) ){
        //el problema es que si se elimina un jugador, el id asignado a cada nuevo cliente se sigue numerando en forma corrida entonces la condicion puede no ser correcta y comenzar la partida cuando no esten aun todos los jugadores conectados
        if(jugadores.size() == numJugadores ){
        //tampoco se soluciona facilmente si pasamos la asignacion de id al gestor partida ya que por mas que aumentemos una variable id cada vez que agregamos o restemos cada vez q eliminemos un jugador, si no se elimina el ultimo jugador se duplicaria un id para dos clientes distintos
            estadoPartida.setJugando();
            comenzarPartida();
            gestorJuego = new GestorJuego(numJugadores, tipoEscenario, gestorSalida, this);
        }
    }
    public void eliminarJugador(int id){
        ((Cliente)jugadores.get(id)).getEnviador().enviar(new MsjFinPartida(id));
        jugadores.remove(id);
        this.id--;
        System.out.println("Jugador eliminado "+id);
    }
    
    public void comenzarPartida(){

        Iterator it = jugadores.entrySet().iterator();
        ArrayList<Personajes> personajes = new ArrayList<Personajes>();

        while(it.hasNext()){
            Map.Entry e = (Map.Entry)it.next();
            personajes.add(new Personajes(((Cliente)e.getValue()).getNombre(), ((Cliente)e.getValue()).getTipoPersonaje(), ((Cliente)e.getValue()).getId()));
        }
        gestorSalida.enviar(tipoEscenario, numJugadores, personajes);
    }
    public void finalizarPartida(int id){
        ((Cliente)jugadores.get(id)).getEnviador().enviar(new MsjFinPartida(-1));
        System.out.println("Finalizando la partida");
        System.exit(0);
    }

    public GestorJuego getGestorJuego(){
        return gestorJuego;
    }
}